﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame1
{
    class Objeto3D
    {
        public Model model;
        public Vector3 position, scale, rotation;
        public float alpha;
        private Matrix worldMatrix;

        public Texture2D textura;
        public BoundingBox collisionBounds;
        

        public Objeto3D(Model model)
        {
            this.model = model;
            

            position = new Vector3(0, 0, 0);
            rotation = new Vector3(0, 0, 0);
            scale = new Vector3(1, 1, 1);

            alpha = 0.5f;

            textura = Game1.Self.Content.Load<Texture2D>("nome");
        }

        public Boolean hitTestObject(Objeto3D objeto)
        {
            this.CalcularBox();
            objeto.CalcularBox();


            if (this.collisionBounds.Intersects(objeto.collisionBounds))
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        public void CalcularBox()
        {
            //Inicia os cantos da caixa com valores maximo e minimo
            Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);

            //para cada malha e submalha no modelo
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
                    //Texture2D[] texturas = new Texture2D[5];
                    int vertexStride = meshPart.VertexBuffer.VertexDeclaration.VertexStride;//o número de bytes de um vértice para o próximo
                    int vertexBufferSize = meshPart.NumVertices * vertexStride;//o tamanho do buffer (array) de vértices
                    float[] vertexData = new float[vertexBufferSize / sizeof(float)];//um array [] com o tamanho certo para caber o vertexBufferSize
                    meshPart.VertexBuffer.GetData<float>(vertexData);//pegar GetData a informação de float e preencher o buffer de vértices
                    //percorrer de i = 0 até o tamanho do buffer de vértices em float andando de float em float (ver cada ponto)
                    for (int i = 0; i < vertexBufferSize / sizeof(float); i += vertexStride / sizeof(float))
                    {
                        //cria um vertor transformado com os tres pontos em relação ao mundo
                        Vector3 transformedPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), WorldMatrix);

                        //calcula os pontos, o mínimo e o máximo
                        min = Vector3.Min(min, transformedPosition);
                        max = Vector3.Max(max, transformedPosition);

                    }
                }
            }

            collisionBounds = new BoundingBox(min, max);
        }



        public Matrix WorldMatrix
        {
            get
            {
                Matrix matrix = Matrix.Identity *
                    Matrix.CreateScale(scale) *
                    Matrix.CreateRotationX(MathHelper.ToRadians(rotation.X)) *
                    Matrix.CreateRotationY(MathHelper.ToRadians(rotation.Y)) *
                    Matrix.CreateRotationZ(MathHelper.ToRadians(rotation.Z)) *
                    Matrix.CreateTranslation(position);
                    
                    


                worldMatrix = matrix;
                return worldMatrix;
            }

            set
            {
                worldMatrix = value;
            }
        }

        public void Draw(Camera3D camera)
        {
            //model.Draw(WorldMatrix, view, projection);

            foreach (ModelMesh malha in model.Meshes)
            {
                foreach (BasicEffect efeito in malha.Effects)
                {
                    efeito.View = camera.View;
                    efeito.Projection = camera.projection;
                    efeito.World = WorldMatrix;

                    efeito.EnableDefaultLighting();
                    efeito.FogEnabled = true;
                    efeito.FogColor = Color.Black.ToVector3();
                    efeito.FogStart = 43f;
                    efeito.FogEnd = 47f;

                    //efeito.TextureEnabled = true;
                    //efeito.Texture = textua;
                    
                }
                
                malha.Draw();
            }
        }
    }
}
